package com.wifiin.springboot.webmagic.conversion;

import com.google.common.collect.Sets;
import com.wifiin.log.LoggerFactory;
import com.wifiin.springboot.webmagic.constant.SougouConstantData;
import com.wifiin.springboot.webmagic.exception.MagicException;
import com.wifiin.util.Help;

import java.io.*;
import java.net.URL;
import java.util.*;

public class CreateTxtFile {
	protected static ByteArrayOutputStream output = new ByteArrayOutputStream();
    private static Set<String> wordSet = Sets.newConcurrentHashSet();
	private LoggerFactory.Logger logger = LoggerFactory.getLogger(CreateTxtFile.class);

	public void writeToTargetFile(String targetFilePath) throws IOException {
		createParentDir(targetFilePath);
		PrintStream printStream = new PrintStream(new File(targetFilePath));
		logger.info("conversion data :"+wordSet.size());
		printStream.println(Help.concat(wordSet,"\n"));
	}

	public void readScelFile(String scelUrlStr) {
		URL url = null;
		InputStream inputStream = null;
		try {
			url = new URL(scelUrlStr);
			inputStream = url.openStream();
		} catch (Exception e) {
			logger.warn("downloadScelFile exception:{}", scelUrlStr);
		}
		DataInputStream input = new DataInputStream(inputStream);
		int read;
		try {
			byte[] bytes = new byte[4];
			input.readFully(bytes);
			input.readFully(bytes);
			int flag = bytes[0];
			int[] reads = new int[]{8};
			readString(input, 0x130, reads);
			readString(input, 0x338, reads);
			read = reads[0];
			input.skip(0x1540 - read);
			read = 0x1540;
			input.readFully(bytes);
			read += 4;
			bytes = new byte[128];
			Map<Integer, String> pyMap = new LinkedHashMap<>();
			while (true) {
				int mark = readUnsignedShort(input);
				int size = input.readUnsignedByte();
				input.skip(1);
				read += 4;
				input.readFully(bytes, 0, size);
				read += size;
				String py = new String(bytes, 0, size, SougouConstantData.SOUGOU_ENCODING);
				pyMap.put(mark, py);
				if ("zuo".equals(py))
					break;
			}
			if (flag == 0x44) {
				input.skip(0x2628 - read);
			} else if (flag == 0x45) {
				input.skip(0x26C4 - read);
			} else {
				logger.warn("read scel file exception");
				throw new MagicException("read scel file exception");
			}
			StringBuilder builder = new StringBuilder();
			while (true) {
				int size = readUnsignedShort(input);
				if (size < 0)
					break;
				int count = readUnsignedShort(input);
				int len = count / 2;
				builder.setLength(0);
				for (int i = 0; i < len; i++) {
					int key = readUnsignedShort(input);
					builder.append(pyMap.get(key)).append("'");
				}
				builder.setLength(builder.length() - 1);
				for (int i = 0; i < size; i++) {
					count = readUnsignedShort(input);
					if (count > bytes.length)
						bytes = new byte[count];
					input.readFully(bytes, 0, count);
					String word = new String(bytes, 0, count, SougouConstantData.SOUGOU_ENCODING);
					input.skip(12);
					wordSet.add(word);
				}
			}
		} catch (Exception e) {
			logger.warn("read scel file exception:{}",e.getCause());
		} finally {
			try {
				inputStream.close();
			} catch (Exception e) {
				logger.warn("read scel file exception:{}",e.getCause());
			}
		}
	}

	protected void createParentDir(String targetFilePath) {
		if (!targetFilePath.endsWith(".txt")) {
			logger.warn("FileUrl exception :{}" , targetFilePath);
			throw new MagicException("FileUrl exception :" + targetFilePath);
		}
		File file = new File(targetFilePath);
		if (!file.getParentFile().exists()) {
			file.getParentFile().mkdirs();
		}
	}

	protected int readUnsignedShort(InputStream in) throws IOException {
		int ch1 = in.read();
		int ch2 = in.read();
		if ((ch1 | ch2) < 0) {
			return Integer.MIN_VALUE;
		}
		return (ch2 << 8) + (ch1 << 0);
	}

	protected String readString(DataInputStream input, int pos, int[] reads) throws IOException {
		int read = reads[0];
		input.skip(pos - read);
		read = pos;
		output.reset();
		while (true) {
			int c1 = input.read();
			int c2 = input.read();
			read += 2;
			if (c1 == 0 && c2 == 0)
				break;
			else {
				output.write(c1);
				output.write(c2);
			}
		}
		reads[0] = read;
		return new String(output.toByteArray(), SougouConstantData.SOUGOU_ENCODING);
	}
}
